<script setup lang="ts">
import { onMounted, ref, watch } from 'vue';
import { Space as ASpace } from 'ant-design-vue';
import { ExperimentOutlined, ReloadOutlined, SendOutlined, SyncOutlined } from '@ant-design/icons-vue';
import { getTenantQueueStatus, sendAsyncMessage, sendAsyncReply, sendSyncMessage } from '@/service/api/mq-message';
import type { MqMessageRequest } from '@/service/api/mq-message';
import { fetchGetAllTenants } from '@/service/api/tenant';
import { fetchApiDefinitions } from '@/service/api/compute';

// 租户选项
const tenantOptions = ref<Array<{ label: string; value: string }>>([]);

// 接口选项
const apiOptions = ref<Array<{ label: string; value: string; inputSchema?: string; outputSchema?: string }>>([]);

// 租户配置
const tenantConfig = ref({
  tenantId: '',
  queueStatus: ''
});

// 接口配置
const apiConfig = ref({
  apiId: '',
  selectedApi: null as Api.Compute.ApiDefinition | null
});

// 发送消息相关状态
const sendFormRef = ref();
const sending = ref(false);
const testing = ref(false);
const sendResult = ref<any>(null);
const sendFormData = ref({
  messageType: 'ASYNC_REQUEST', // 消息发送类型
  content: '',
  timeout: 5000
});

// 响应面板状态
const activeResponsePanels = ref<string[]>(['header', 'body']); // 默认展开所有面板

// 配置选项
const messageTypeOptions = [
  { label: '异步请求消息', value: 'ASYNC_REQUEST' },
  { label: '同步请求消息', value: 'SYNC' }
];

// 测试租户队列连接
// 功能：调用后端队列状态接口，基于统一请求封装返回 TenantQueueStatus，避免旧 ApiResponse 判断
const handleTestTenantConnection = async () => {
  if (!tenantConfig.value.tenantId.trim()) {
    window.$message?.warning('请选择租户');
    return;
  }

  testing.value = true;
  try {
    const { data: status, error } = await getTenantQueueStatus(tenantConfig.value.tenantId);
    if (status) {
      tenantConfig.value.queueStatus = status.isListening ? 'LISTENING' : 'NOT_LISTENING';
      window.$message?.success(`租户队列状态: ${tenantConfig.value.queueStatus}`);
    } else {
      // 未返回数据时交由拦截器处理，不额外弹窗
      tenantConfig.value.queueStatus = '连接失败';
      if (error) {
        console.error('测试租户连接失败:', error);
      }
    }
  } finally {
    testing.value = false;
  }
};

// 发送消息功能
const handleSendMessage = async () => {
  if (!tenantConfig.value.tenantId.trim()) {
    window.$message?.error('请输入租户ID');
    return;
  }

  if (!sendFormData.value.content.trim()) {
    window.$message?.error('请输入消息内容');
    return;
  }

  sending.value = true;
  try {
    // 构造请求参数
    // 确保消息内容中包含必要的字段
    const messageContent = JSON.parse(sendFormData.value.content);

    // 确保header存在
    if (!messageContent.header) {
      messageContent.header = {};
    }

    // 确保traceId存在
    if (!messageContent.header.traceId) {
      messageContent.header.traceId = Math.random().toString(36).substr(2, 9);
    }

    // 确保其他必要字段存在
    if (!messageContent.header.version) {
      messageContent.header.version = '1.0';
    }

    // 更新消息内容
    sendFormData.value.content = JSON.stringify(messageContent, null, 2);

    const requestData: MqMessageRequest = {
      message: sendFormData.value.content,
      properties: {
        url: apiConfig.value.selectedApi ? `/compute/${apiConfig.value.selectedApi.bizCode}` : '/compute/default',
        contentType: 'application/json'
      }
    };

    let response: any;

    // 根据消息类型调用不同的接口
    switch (sendFormData.value.messageType) {
      case 'ASYNC_REQUEST':
        response = await sendAsyncMessage(tenantConfig.value.tenantId, requestData);
        break;
      case 'SYNC':
        response = await sendSyncMessage(tenantConfig.value.tenantId, requestData, sendFormData.value.timeout);
        break;
      case 'ASYNC_REPLY':
        response = await sendAsyncReply(tenantConfig.value.tenantId, requestData);
        break;
      default:
        throw new Error('未知的消息类型');
    }

    // 处理响应
    if (typeof response === 'string') {
      // 异步请求和异步回复返回字符串
      sendResult.value = {
        success: true,
        messageId: `msg-${Date.now()}`,
        tenantId: tenantConfig.value.tenantId,
        timestamp: new Date().toISOString(),
        response,
        messageType: sendFormData.value.messageType
      };
      window.$message?.success('消息发送成功');
    } else if (response && typeof response === 'object') {
      // 同步消息返回对象
      sendResult.value = {
        success: true,
        messageId: `msg-${Date.now()}`,
        tenantId: tenantConfig.value.tenantId,
        timestamp: new Date().toISOString(),
        response,
        messageType: sendFormData.value.messageType
      };
      window.$message?.success('消息发送成功并收到响应');
    } else {
      sendResult.value = {
        success: false,
        messageId: '',
        tenantId: tenantConfig.value.tenantId,
        timestamp: new Date().toISOString(),
        error: '未知响应格式'
      };
      window.$message?.error('消息发送失败：未知响应格式');
    }
  } catch (error: any) {
    console.error('发送消息失败:', error);
    sendResult.value = {
      success: false,
      messageId: '',
      tenantId: tenantConfig.value.tenantId,
      timestamp: new Date().toISOString(),
      error: error.message || '网络请求失败'
    };
    window.$message?.error(`消息发送失败: ${error.message || '网络请求失败'}`);
  } finally {
    sending.value = false;
  }
};

const handleSendReset = () => {
  sendFormData.value = {
    messageType: 'ASYNC_REQUEST',
    content: '',
    timeout: 5000
  };
  sendResult.value = null;
};

// 临时移除，将在generateMessageFromSchema函数之后重新定义

// 加载租户列表
const loadTenantOptions = async () => {
  try {
    const response = await fetchGetAllTenants();
    if (response.data && Array.isArray(response.data)) {
      tenantOptions.value = response.data.map((tenant: Api.SystemManage.Tenant) => ({
        label: `${tenant.tenantCode} - ${tenant.tenantName}`,
        value: tenant.id.toString()
      }));
    }
  } catch (error: any) {
    window.$message?.error(`加载租户列表失败：${error.message || '未知错误'}`);
  }
};

// 加载接口列表
const loadApiOptions = async () => {
  try {
    const response = await fetchApiDefinitions();
    if (response && Array.isArray(response)) {
      apiOptions.value = response
        .filter(api => api.status === 'enabled') // 只显示启用的接口
        .map((api: Api.Compute.ApiDefinition) => ({
          label: `${api.name} (${api.bizCode})`,
          value: api.id
        }));
    }
  } catch (error: any) {
    window.$message?.error(`加载接口列表失败：${error.message || '未知错误'}`);
  }
};

// 根据JSON Schema生成示例数据
const generateExampleFromSchema = (schema: any): any => {
  if (!schema || typeof schema !== 'object') {
    return {};
  }

  if (schema.type === 'object' && schema.properties) {
    const result: any = {};
    Object.keys(schema.properties).forEach(key => {
      const property = schema.properties[key];
      result[key] = generateExampleFromSchema(property);
    });
    return result;
  }

  if (schema.type === 'array' && schema.items) {
    return [generateExampleFromSchema(schema.items)];
  }

  switch (schema.type) {
    case 'string':
      return schema.example || `示例${schema.title || '字符串'}`;
    case 'number':
    case 'integer':
      return schema.example || 123;
    case 'boolean':
      return schema.example !== undefined ? schema.example : true;
    default:
      return schema.example || null;
  }
};

// 根据流程定义生成消息内容
const generateMessageFromSchema = (api: Api.Compute.ApiDefinition) => {
  let inputSchema = null;

  // 尝试从流程定义中获取第一个步骤的inputSchema
  if (api.flowDefinition) {
    try {
      const flowDef = JSON.parse(api.flowDefinition);
      if (flowDef.steps && flowDef.steps.length > 0) {
        const firstStep = flowDef.steps[0];
        if (firstStep.type === 'input_param' && firstStep.inputSchema) {
          inputSchema = firstStep.inputSchema;
        }
      }
    } catch (error) {
      console.warn('解析流程定义失败:', error);
    }
  }

  if (!inputSchema) {
    // 如果没有找到inputSchema，生成基本的测试消息
    const basicMessage = {
      header: {
        bizCode: api.bizCode,
        tenantId: tenantConfig.value.tenantId,
        timestamp: Date.now(),
        traceId: Math.random().toString(36).substr(2, 9)
      },
      body: {
        message: `测试消息 - ${api.name}`
      }
    };
    sendFormData.value.content = JSON.stringify(basicMessage, null, 2);
    return;
  }

  try {
    // 尝试解析inputSchema并生成示例数据
    const schema = typeof inputSchema === 'string' ? JSON.parse(inputSchema) : inputSchema;
    const exampleData = generateExampleFromSchema(schema);

    // 构造完整的消息结构
    const messageContent = {
      header: {
        bizCode: api.bizCode,
        tenantId: tenantConfig.value.tenantId,
        timestamp: Date.now(),
        traceId: Math.random().toString(36).substr(2, 9)
      },
      body: exampleData
    };

    sendFormData.value.content = JSON.stringify(messageContent, null, 2);
  } catch (error) {
    console.warn('解析inputSchema失败，使用基本消息格式:', error);
    // 如果解析失败，使用基本格式
    const basicMessage = {
      header: {
        bizCode: api.bizCode,
        tenantId: tenantConfig.value.tenantId,
        timestamp: Date.now(),
        traceId: Math.random().toString(36).substr(2, 9)
      },
      body: {
        message: `测试消息 - ${api.name}`
      }
    };
    sendFormData.value.content = JSON.stringify(basicMessage, null, 2);
  }
};

// 处理接口选择
const handleApiChange = async (value: any) => {
  const apiId = value ? String(value) : '';
  if (!apiId) {
    apiConfig.value.selectedApi = null;
    return;
  }

  try {
    const response = await fetchApiDefinitions();
    if (response && Array.isArray(response)) {
      const selectedApi = response.find(api => api.id === apiId);
      if (selectedApi) {
        apiConfig.value.selectedApi = selectedApi;
        // 根据接口的inputSchema自动生成消息内容
        generateMessageFromSchema(selectedApi);
      }
    }
  } catch (error: any) {
    window.$message?.error(`获取接口详情失败：${error.message || '未知错误'}`);
  }
};

// 生成测试消息
const handleGenerateTestMessage = () => {
  // 如果选择了接口，使用接口Schema生成消息
  if (apiConfig.value.selectedApi) {
    generateMessageFromSchema(apiConfig.value.selectedApi);
    return;
  }

  // 否则使用默认的测试消息
  const testMessages: Record<string, string> = {
    ASYNC_REQUEST: `异步请求测试消息，发送时间: ${new Date().toLocaleString()}`,
    SYNC: JSON.stringify(
      {
        type: 'sync_test',
        message: '这是一条同步测试消息',
        timestamp: new Date().toISOString(),
        data: {
          id: Math.random().toString(36).substr(2, 9),
          value: Math.floor(Math.random() * 1000)
        }
      },
      null,
      2
    ),
    ASYNC_REPLY: `异步回复测试消息，发送时间: ${new Date().toLocaleString()}`
  };

  sendFormData.value.content = testMessages[sendFormData.value.messageType] || testMessages.ASYNC_REQUEST;
};

// 监听租户和接口变化，自动重新生成消息和测试连接
watch([() => tenantConfig.value.tenantId, () => apiConfig.value.apiId], ([newTenantId, _newApiId], [oldTenantId]) => {
  // 当租户ID变化时，自动测试连接
  if (newTenantId && newTenantId !== oldTenantId) {
    handleTestTenantConnection();
  }

  // 当接口选择变化时，生成测试消息
  if (apiConfig.value.selectedApi) {
    generateMessageFromSchema(apiConfig.value.selectedApi);
  }
});

// 页面初始化
onMounted(() => {
  // 加载租户列表
  loadTenantOptions();
  // 加载接口列表
  loadApiOptions();
  // 页面加载时获取租户队列状态
  handleTestTenantConnection();
});
</script>

<template>
  <ASpace direction="vertical" style="width: 100%" :size="16">
    <!-- 顶部配置区域 -->
    <ARow :gutter="16">
      <!-- 左侧：租户配置 -->
      <ACol :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
        <ACard title="租户配置" size="small" class="config-card">
          <ARow :gutter="[16, 16]" align="middle">
            <ACol :span="24">
              <ASpace.Compact style="width: 100%">
                <AInput value="租户ID" disabled class="label-input" />
                <ASelect
                  v-model:value="tenantConfig.tenantId"
                  :options="tenantOptions"
                  show-search
                  :filter-option="(input, option) => option?.label?.toLowerCase().includes(input.toLowerCase())"
                  allow-clear
                  style="flex: 1"
                  placeholder="请选择租户"
                />
              </ASpace.Compact>
            </ACol>

            <ACol v-if="tenantConfig.queueStatus" :span="24">
              <ATag
                :color="tenantConfig.queueStatus.includes('监听中') ? 'success' : 'warning'"
                style="margin-top: 4px"
              >
                状态: {{ tenantConfig.queueStatus }}
              </ATag>
            </ACol>
          </ARow>
        </ACard>
      </ACol>

      <!-- 右侧：接口配置 -->
      <ACol :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
        <ACard title="接口配置" size="small" class="config-card">
          <ARow :gutter="[16, 16]" align="middle">
            <ACol :span="24">
              <ASpace.Compact style="width: 100%">
                <AInput value="选择接口" disabled class="label-input" />
                <ASelect
                  v-model:value="apiConfig.apiId"
                  :options="apiOptions"
                  show-search
                  :filter-option="(input, option) => option?.label?.toLowerCase().includes(input.toLowerCase())"
                  allow-clear
                  style="flex: 1"
                  placeholder="请选择接口"
                  @change="handleApiChange"
                />
              </ASpace.Compact>
            </ACol>
            <ACol v-if="apiConfig.selectedApi" :span="24">
              <ATag color="blue" style="margin-top: 4px">
                已选择: {{ apiConfig.selectedApi.name }} - {{ apiConfig.selectedApi.bizCode }}
              </ATag>
            </ACol>
            <ACol v-else :span="24">
              <ATypographyText type="secondary" style="margin-top: 4px; display: block">
                选择接口后将自动生成消息内容
              </ATypographyText>
            </ACol>
          </ARow>
        </ACard>
      </ACol>
    </ARow>

    <!-- 功能区域 -->
    <div class="function-content">
      <ARow :gutter="16">
        <!-- 左侧：消息表单 -->
        <ACol :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
          <ACard size="small" class="form-card" title="消息配置">
            <AForm ref="sendFormRef" layout="vertical">
              <ARow :gutter="16">
                <ACol :xs="24" :sm="12">
                  <AFormItem label="消息类型">
                    <ASelect
                      v-model:value="sendFormData.messageType"
                      placeholder="选择消息类型"
                      :options="messageTypeOptions"
                    />
                  </AFormItem>
                </ACol>
                <ACol :xs="24" :sm="12">
                  <AFormItem v-if="sendFormData.messageType === 'SYNC'" label="超时时间(毫秒)">
                    <AInput
                      v-model:value="sendFormData.timeout"
                      type="number"
                      placeholder="同步消息超时时间"
                      :min="1000"
                      :max="30000"
                    />
                  </AFormItem>
                </ACol>
              </ARow>
              <AFormItem label="消息内容">
                <ATextarea
                  v-model:value="sendFormData.content"
                  placeholder="请输入消息内容"
                  :rows="8"
                  show-count
                  :maxlength="10000"
                  class="code-textarea"
                />
              </AFormItem>

              <AFormItem>
                <ASpace :size="8">
                  <AButton type="primary" :loading="sending" @click="handleSendMessage">
                    <template #icon>
                      <SendOutlined v-if="sendFormData.messageType !== 'SYNC'" />
                      <SyncOutlined v-else />
                    </template>
                    {{ sendFormData.messageType === 'SYNC' ? '发送同步消息' : '发送异步消息' }}
                  </AButton>
                  <AButton @click="handleGenerateTestMessage">
                    <template #icon><ExperimentOutlined /></template>
                    生成测试消息
                  </AButton>
                  <AButton @click="handleSendReset">
                    <template #icon><ReloadOutlined /></template>
                    重置
                  </AButton>
                </ASpace>
              </AFormItem>
            </AForm>
          </ACard>
        </ACol>

        <!-- 右侧：结果展示 -->
        <ACol :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
          <ACard
            :title="sendResult ? (sendResult.success ? '发送成功' : '发送失败') : '消息结果'"
            class="result-card"
            :class="{
              'success-card': sendResult && sendResult.success,
              'error-card': sendResult && !sendResult.success,
              'empty-result': !sendResult
            }"
            size="small"
          >
            <template v-if="sendResult">
              <!-- 消息基本信息 -->
              <ADescriptions :column="1" bordered size="small" style="margin-bottom: 16px">
                <ADescriptionsItem label="消息ID">
                  {{ sendResult.messageId || 'N/A' }}
                </ADescriptionsItem>
                <ADescriptionsItem label="租户ID">
                  {{ sendResult.tenantId }}
                </ADescriptionsItem>
                <ADescriptionsItem label="消息类型">
                  {{ sendResult.messageType }}
                </ADescriptionsItem>
                <ADescriptionsItem label="发送时间">
                  {{ new Date(sendResult.timestamp).toLocaleString() }}
                </ADescriptionsItem>
                <ADescriptionsItem v-if="sendResult.error" label="错误信息">
                  <ATypographyText type="danger">
                    {{ sendResult.error }}
                  </ATypographyText>
                </ADescriptionsItem>
              </ADescriptions>

              <!-- 服务器响应部分 -->
              <template v-if="sendResult.response">
                <div class="response-section">
                  <!-- 使用折叠面板展示响应内容 -->
                  <ACollapse v-model:active-key="activeResponsePanels" :bordered="false">
                    <!-- Header 部分 -->
                    <ACollapsePanel key="header" header="Header" :style="{ borderRadius: '4px', marginBottom: '8px' }">
                      <ATypographyParagraph style="margin: 0">
                        <pre>{{
                          typeof sendResult.response === 'string'
                            ? '无header信息'
                            : sendResult.response.data && sendResult.response.data.header
                              ? JSON.stringify(sendResult.response.data.header, null, 2)
                              : '无header信息'
                        }}</pre>
                      </ATypographyParagraph>
                    </ACollapsePanel>

                    <!-- Body 部分 -->
                    <ACollapsePanel key="body" header="Body" :style="{ borderRadius: '4px' }">
                      <ATypographyParagraph style="margin: 0">
                        <pre>{{
                          typeof sendResult.response === 'string'
                            ? sendResult.response
                            : sendResult.response.data &&
                                sendResult.response.data.body &&
                                sendResult.response.data.body.data
                              ? JSON.stringify(sendResult.response.data.body.data, null, 2)
                              : sendResult.response.data && sendResult.response.data.body
                                ? JSON.stringify(sendResult.response.data.body, null, 2)
                                : '无body信息'
                        }}</pre>
                      </ATypographyParagraph>
                    </ACollapsePanel>
                  </ACollapse>
                </div>
              </template>
            </template>
            <template v-else>
              <div class="empty-result-content">
                <SendOutlined style="font-size: 32px; color: #d9d9d9; margin-bottom: 16px" />
                <p>发送消息后将在此处显示结果</p>
              </div>
            </template>
          </ACard>
        </ACol>
      </ARow>
    </div>
  </ASpace>
</template>

<style scoped>
.mq-test-card {
  margin-bottom: 16px;
}

.config-card {
  height: 100%;
  transition: all 0.3s;
}

.label-input {
  width: 80px;
  text-align: center;
  /* background-color: #fafafa; */
}

.form-card {
  height: 100%;
  transition: all 0.3s;
}

.result-card {
  height: 100%;
  transition: all 0.3s;
}

.success-card {
  border-color: #52c41a;
}

.error-card {
  border-color: #ff4d4f;
}

.empty-result {
  border-color: #d9d9d9;
}

.empty-result-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 32px 0;
  color: #8c8c8c;
  text-align: center;
}

.code-textarea {
  font-family: monospace;
  font-size: 14px;
}

/* 修复按钮图标与文字错位问题 */
:deep(.ant-btn) {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

:deep(.ant-btn-icon) {
  margin-right: 0px;
}

pre {
  /* background-color: #f5f5f5; */
  padding: 12px;
  border-radius: 4px;
  font-size: 13px;
  overflow-x: auto;
  margin: 0;
  font-family: monospace;
  max-height: 300px;
  overflow-y: auto;
  white-space: pre-wrap;
  word-break: break-all;
}

.function-content {
  transition: all 0.3s;
}

.response-section {
  margin-top: 8px;
}

/* 自定义折叠面板样式 */
:deep(.ant-collapse-header) {
  font-weight: 500;
}

:deep(.ant-collapse-content-box) {
  padding: 0 !important;
}

:deep(.ant-collapse) {
  background: transparent;
}
</style>
